package org.dna.wickwtui.users;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

import org.apache.log4j.Logger;
import org.apache.wicket.Component;
import org.apache.wicket.markup.html.basic.Label;
import org.apache.wicket.markup.html.form.CheckBox;
import org.apache.wicket.markup.html.form.Form;
import org.apache.wicket.markup.html.form.SubmitLink;
import org.apache.wicket.markup.html.link.Link;
import org.apache.wicket.markup.html.list.ListItem;
import org.apache.wicket.markup.html.list.PageableListView;
import org.apache.wicket.markup.html.navigation.paging.PagingNavigator;
import org.apache.wicket.markup.html.panel.Panel;
import org.apache.wicket.model.CompoundPropertyModel;
import org.apache.wicket.model.IModel;
import org.dna.MetroApplication;
import org.dna.UserRoles;
import org.dna.metronomo.persistence.User;
import org.dna.uimodel.LoadableUserModel;
import org.dna.uimodel.MenuItem;
import org.dna.uimodel.SelectableUser;

/**
 * This panel contains the pageable list of all users defined in the system.
 */
@UserRoles( { "admin", "project_manager" })
public class UserListPanel extends Panel implements IContextMenuProvider {

    private final static Logger LOG = Logger.getLogger(UserListPanel.class);

	@UserRoles( { "admin", "user" })
	private class DetailsUserLink extends Link<User> {
		private static final long serialVersionUID = 5465622432088190541L;

		public DetailsUserLink(String id, IModel<User> user) {
			super(id, user);
		}

		@Override
		public void onClick() {
			((ManageUserPage) getPage()).switchToPanel(UserDetailsPanel.class,
					getModelObject());
		}
	}

	@UserRoles( { "admin", "user" })
	private class DeleteUsersLink extends SubmitLink {

		private static final long serialVersionUID = -5681232486590259371L;

		public DeleteUsersLink(String id) {
			super(id, m_form);
		}

		@Override
		public void onSubmit() {
			// TODO call the backend and update the view, AJAX??
            LOG.info("Removing selected users");
			int[] idstoDel = collectDeleted();
			MetroApplication.get().getUserDAO().deleteByID(idstoDel);
            m_users.detach(); //force the detach to update the list at next usage
            LOG.debug("Update the users table with " + m_users.getObject());
		}

		private int[] collectDeleted() {
			List<Integer> l = new ArrayList<Integer>();
			for (User user : m_users.getObject()) {
				SelectableUser suser = (SelectableUser) user;
				if (suser.isSelected()) {
					l.add(user.getId());
                    LOG.debug("Adding selected user " + user);
				}
			}

			// Copy the list of Integer to int[]
			int[] ret = new int[l.size()];
			for (int i = 0; i < ret.length; i++) {
				ret[i] = l.get(i);
			}
            LOG.debug("Selected user IDs " + Arrays.toString(ret));
			return ret;
		}
	}

	Form<List<? extends User>> m_form;
	IModel<List<SelectableUser>> m_users;
	PageableListView<User> m_usersView;
	private static final int ITEM_PER_PAGE = 50;
	private static final long serialVersionUID = 1L;

	public UserListPanel(String id, IModel<List<SelectableUser>> users) {
		super(id);
		m_users = users;
		initComponents(users);
	}

	private void initComponents(IModel<List<SelectableUser>> users) {
		m_form = new Form<List<? extends User>>("form"){
			@Override
			public void onSubmit() {
                LOG.debug("Actually selected user for deletion " + m_users);
			}
		};
		m_usersView = new PageableListView<User>("users", users, ITEM_PER_PAGE) {

			@Override
			protected void populateItem(ListItem<User> item) {
				User user = item.getModelObject();
				IModel<User> userModel = new LoadableUserModel(user);
				
				item.setModel(new CompoundPropertyModel<User>(userModel));

				DetailsUserLink link = new DetailsUserLink("link", userModel);
				link.add(new Label("name"));
				item.add(new CheckBox("selected"));
				item.add(link);
				item.add(new Label("role"));
			}
		};
//		m_usersView.setReuseItems(true);
		m_form.add(m_usersView);
		add(m_form);
		add(new PagingNavigator("navigator", m_usersView));
	}

	public List<MenuItem> prepare() {
		MenuItem deleteSelectedUsersItem = new MenuItem("Delete",
				ManageUserPage.class) {

			@Override
			public Component createMenu() {
				DeleteUsersLink link = new DeleteUsersLink("link");
				link.add(new Label("caption", getCaption()));
				return link;
			}
		};
		return Arrays.asList(deleteSelectedUsersItem);
	}
}
